package com.harboursoftware.xstorage.db.sql;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;

import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.RowProcessor;
import org.apache.commons.dbutils.handlers.BeanHandler;

import com.harboursoftware.xstorage.XStorageException;
import com.harboursoftware.xstorage.ac.AccessControlPolicy;
import com.harboursoftware.xstorage.db.UserDao;
import com.harboursoftware.xstorage.model.XBucket;
import com.harboursoftware.xstorage.model.XUser;

/**
 * 
 * @author Simon Leung
 * @since 0.1
 */
class BucketRowProcessor extends BaseRowProcessor {
    private UserDao userSqlDao;

    private RowProcessor acpRowProcessor;
    private ResultSetHandler<AccessControlPolicy> acpBeanHandler;
    private DatabaseProvider databaseProvider;

    public BucketRowProcessor(DatabaseProvider databaseProvider) {
        this.databaseProvider = databaseProvider;
        userSqlDao = new UserSqlDao(databaseProvider);
        acpRowProcessor = new AcpRowProcessor(databaseProvider);
        acpBeanHandler = new BeanHandler<AccessControlPolicy>(AccessControlPolicy.class, acpRowProcessor);
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T> T toBean(ResultSet rs, Class<T> type) throws SQLException {
        String name = rs.getString("name");
        String ownerId = rs.getString("owner");
        Date creationDate = rs.getDate("creation_date");
        XUser owner = findUserById(ownerId);

        AccessControlPolicy acp = findAcpByBucketName(name);

        XBucket bucket = new XBucket(name, owner, acp);
        bucket.setCreationDate(creationDate);
        
        return (T)bucket;
    }

    private XUser findUserById(String id) throws SQLException {
        try {
            return userSqlDao.findUserById(id);
        } catch (XStorageException e) {
            throw new SQLException(e);
        }
    }

    private AccessControlPolicy findAcpByBucketName(String bucketName) throws SQLException {
        Connection connection;
        connection = databaseProvider.getConnection();
       
        String sql = "SELECT * FROM x_access_control_policy WHERE bucket=?";
        QueryRunner sqlRunner = new QueryRunner();
        AccessControlPolicy acp = sqlRunner.query(connection, sql, acpBeanHandler, bucketName);
        DbUtils.closeQuietly(connection);
        return acp;
    }
}
